package mshop.com.schild_kotlin.custom_media_player;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import tv.danmaku.ijk.media.player.misc.IMediaDataSource;

import static java.net.HttpURLConnection.HTTP_OK;
import static java.net.HttpURLConnection.HTTP_PARTIAL;

/**
 * Created by mayi on 2018/5/30.
 *
 * @Autor CaiWF
 * @Email 401885064@qq.com
 * @TODO
 */
public class OkHttpIMediaDataSource implements IMediaDataSource {


    private final OkHttpClient mClient;
    private final String mUrl;
    private Response mResponse;
    private InputStream mInputStream;
    private byte[] mTailData;
    private long mLength = Integer.MAX_VALUE, mCurrOffset = -1, mTailSize = -1;

    public OkHttpIMediaDataSource(String url) {

        mUrl = url;
        mClient = new OkHttpClient();
//        mClient =OkHttpClientUtil.getInstall().getHttpBuilder(30 * 1000, mUrl).build();
    }
    private Response request(long offset) throws IOException {
        Request.Builder builder = new Request.Builder().url(mUrl).get();

        if (offset > 0) {
            builder.addHeader("Range", String.format("bytes=%d-", offset));
        }

        Response response = mClient.newCall(builder.build()).execute();
        if (response.isSuccessful()) {
            mLength = readSourceAvailableBytes(response, offset, response.code());
            return response;
        }

        throw new IOException(String.format("Url[%s] error! code[%d]", mUrl, response.code()));
    }

    private long readSourceAvailableBytes(Response response, long offset, int responseCode) throws IOException {
        long contentLength = response.body().contentLength();
        return responseCode == HTTP_OK ? contentLength : responseCode == HTTP_PARTIAL ? contentLength + offset : Integer.MAX_VALUE;
    }


    @Override
    public int readAt(long position, byte[] buffer, int offset, int size) throws IOException {
        return readOnceFromServer(buffer, position + offset);
    }

    @Override
    public long getSize() throws IOException {
        if (mInputStream != null) return mInputStream.available();
        return 0;
    }

    @Override
    public void close() {
        close(mInputStream, mResponse);
        mInputStream = null;
        mResponse = null;
        mCurrOffset = -1;
    }


    private void close(InputStream is, Response response) {
        try {
            if (is != null) {
                is.close();
            }

            if (response != null) {
                response.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    final int readOnceFromServer(byte[] buffer, long offset) throws IOException {
        Response response = null;
        InputStream is = null;
        int count = 0;
        int read;
        try {
            response = request(offset);
            is = response.body().byteStream();
            byte[] data = new byte[8192];
            while ((read = is.read(data, 0, data.length)) != -1) {
                if (buffer.length < (count + read)) {
                    read = buffer.length - count;
                    if (read == 0) {
                        break;
                    }
                }
                System.arraycopy(data, 0, buffer, count, read);
                count += read;
            }

            mTailSize = offset;
            mTailData = Arrays.copyOf(buffer, count);
        } finally {
            close(is, response);
        }
        return count;
    }

}
